/**
 * 安卓白金英雄坛制作组 <br>
 * 文件名：Gmud.java <br>
 * 创建时间：2014-5-18 下午2:24:38 <br>
 * 所属项目：GmudEX <br>
 * @author 12548 <br>
 */
package lostland.gmud.exv2;

import android.app.Application;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import lostland.gmud.exv2.blgframework.impl.BLGFileIO;
import lostland.gmud.exv2.data.Gesture;
import lostland.gmud.exv2.data.GmudMap;
import lostland.gmud.exv2.data.ItemTemplate;
import lostland.gmud.exv2.data.MainChar;
import lostland.gmud.exv2.data.Npc;
import lostland.gmud.exv2.data.Skill;
import lostland.gmud.exv2.data.TalentDesc;
import lostland.gmud.exv2.data.TriggerCondition;
import lostland.gmud.exv2.data.TriggerEvent;
import lostland.gmud.exv2.expand.DesUtils;
import lostland.gmud.exv2.expand.GmudPayment;

/**
 * 类名：Gmud <br>
 * 说明：应用类。
 *
 * @author 12548
 */
public class Gmud extends Application {

	public static final boolean DEBUG = BuildConfig.DEBUG; //FIXME 在发布时一定要改成false

	public static final Random rand = new Random(System.nanoTime());
	public static GmudMap maps[];
//	public static Bitmap maps_bitmap[][];
	public static MainChar mc;
	public static Skill skill[];
	public static ArrayList<Gesture> zs;
	private static ArrayList<ItemTemplate> wp;
	private static ArrayList<Npc> npc;
	private static SparseArray<TalentDesc> talent_desc;
	public static final SparseBooleanArray temp_switches = new SparseBooleanArray();
	public static final SparseIntArray temp_variavble = new SparseIntArray();
	public static ArrayList<TriggerCondition> conditions = new ArrayList<>();
	public static ArrayList<TriggerEvent> events = new ArrayList<>();
	public static int tileset = 1; // 图块集

	private static String[] factionName;

	public static String getFactionName(int i) {

		if(factionName == null){
			factionName = LoadingScreen.loadFactionJson();
		}

		return factionName[i];
	}

	public static int getFactionCount() {

		if(factionName == null){
			factionName = LoadingScreen.loadFactionJson();
		}

		return factionName.length;
	}

	public static final String PFKEY_PAYMENTDATA = "payments";

	public static ArrayList<ItemTemplate> getWp() {
		if(wp == null) {
			wp = LoadingScreen.loadItemJson();
		}
		return wp;
	}

//	public static ArrayList<GmudPayment> payments = new ArrayList<>();

	public enum PaymentStatus {
		TRIAL,    //体验阶段
		TRIAL2,   //继续体验
		ZERO,     //不给钱
		PAID      //给钱了
	}

	public static class PaymentData {

		public HashMap<String, GmudPayment> payments = new HashMap<>();
		public PaymentStatus paymentStatus = PaymentStatus.TRIAL;

		public void saveLocal() {
			SharedPreferences pf = Game.getInstance().getFileIO().getPreferences();

			Editor edit = pf.edit();

			try {
				edit.putString(PFKEY_PAYMENTDATA, new DesUtils("awerfasd").encrypt(new Gson().toJson(this)));
				while (!edit.commit()) {
				}
			} catch (Exception e) {
				if (DEBUG) {
					e.printStackTrace();
				}
				return;
			}
		}
	}

	public static PaymentData paymentData = new PaymentData();

	/**
	 * 在数组末尾插入元素
	 *
	 * @param a    数组
	 * @param item 元素
	 * @return
	 */
	public static int[] push_back(int[] a, int item) {
		int t[] = new int[a.length + 1];
		System.arraycopy(a, 0, t, 0, a.length);
		t[a.length] = item;
		return t;
	}

	/**
	 * 在数组开头插入元素
	 *
	 * @param a    数组
	 * @param item 元素
	 * @return
	 */
	public static int[] push_top(int[] a, int item) {
		int t[] = new int[a.length + 1];
		t[0] = item;
		System.arraycopy(a, 0, t, 1, t.length - 1);
		return t;
	}

	/**
	 * 判断数组是否包含某元素
	 *
	 * @param a    数组
	 * @param item 元素
	 * @return
	 */
	public static boolean contains(int[] a, int item) {
		for (int i : a)
			if (i == item)
				return true;
		return false;
	}

	public static int bool2int(boolean b) {
		if (b)
			return 1;
		else
			return 0;
	}

	public static boolean int2bool(int a) {
		return a != 0;
	}

	/**
	 * ArrayList转换为一维数组
	 *
	 * @param al 要转换的ArrayList
	 * @return 转换出的数组
	 */
	public static String[] al2ar(ArrayList<String> al) {
		String t[] = new String[al.size()];

		for (int i = 0; i < al.size(); i++) {
			t[i] = al.get(i);
		}

		return t;
	}

	/**
	 * 武功等级描述
	 *
	 * @param lvl 等级描述编号
	 * @return
	 */
	public static String getLvlDesc(int lvl) {
		if (lvl < GameConstants.pj.length)
			return GameConstants.pj[lvl];
		else
			return "极其变态";
	}

	/**
	 * 所有授业师傅的id
	 */
	public static final int teachers[] = {38, 43, 47, 56, 57, 58, 66, 73, 80, 87, 90, 94, 96, 97, 101, 122, 118, 110};

	/**
	 * 每个门派的授业师傅的id
	 */
	public static final int t_faction[][] = {{}, {38, 43, 47}, {96, 97, 101}, {56, 57, 58, 66}, {87, 90, 94}, {73, 80}, {110, 118, 122}};

	public static int[] bool2int(boolean[] bl) {
		int[] t = new int[bl.length];

		for (int i = 0; i < bl.length; i++) {
			t[i] = bool2int(bl[i]);
		}

		return t;
	}

	/**
	 * 获取中文字符串在12像素大小时的长度
	 *
	 * @param s 字符串
	 */
	public static int StringLength(String s) {
		int t = 0;
		byte[] buffer;
		try {
			buffer = s.getBytes("GBK");

			for (int i = 0; i < buffer.length; i++) {
				byte b = buffer[i];
				if ((b & 0xFF) < 0xA0) {
					t += 6;
				} else {
					t += 12;
					i++;
				}
			}

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return t;
	}

	/**
	 * 查找指定名称的物品
	 *
	 * @param name 物品名
	 * @return Item
	 */
	public static ItemTemplate findItem(String name) {
		for (ItemTemplate wp : Gmud.getWp()) {
			if (wp.getName().contains(name))
				return wp;
		}
		throw new RuntimeException("物品未找到！");
	}

	public static Skill findSkill(String name) {
		for (Skill skl : Gmud.skill) {
			if (skl.name.equals(name))
				return skl;
		}
		throw new RuntimeException("物品未找到！");
	}

	/**
	 * 查找指定姓名的NPC
	 *
	 * @param name 姓名
	 * @return NPC
	 */
	public static Npc findNpc(String name) {
		return Gmud.getNpc(findNpcId(name));
	}

	public static int findNpcId(String name) {
		for(int i = 0; i < Gmud.getNpc().size(); i++) {
			if(npc.get(i).name.equals(name)) {
				com.orhanobut.logger.Logger.v("NPC found : %s is equal to %s on %d", npc.get(i).name, name, i);
				return i;
			}
		}
		throw new RuntimeException("物品未找到！");
	}

	/**
	 * 对数值进行上下限的处理
	 *
	 * @param data        目标值
	 * @param lower_limit 下限 =-1 则不进行限制
	 * @param upper_limit 上限 =-1 则不进行限制
	 * @return 修正后的值
	 * @see lostland.gmud.exv2.data.Room#validity_rectify()
	 */
	public static int format(int data, int lower_limit, int upper_limit) {
		int value = data;
		//limit = -1 则不进行限制
		if (lower_limit != -1) {
			value = Math.max(lower_limit, value);
		}
		if (upper_limit != -1) {
			value = Math.min(upper_limit, value);
		}
		return value;
	}

	/**
	 * 获取背景色。背景色取决于是否开启传统单色模式。
	 *
	 * @return 背景色
	 */
	public static int getBgColor() {
		return BG_COLOR[tileset];
	}


	private static final int BG_COLOR[] = {0xFFA8B281, 0xFFC39D76, 0xFF70AB46};

	/**
	 * 获取日历字符串。
	 *
	 * @return 日历字符串。
	 */
	public static String getCalString() {

		MapScreen.timeCheck();

		final String GAN[] = new String[]{
				"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"
		};

		final String ZHI[] = new String[]{
				"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
		};

		final String MONTH[] = new String[]{
				"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"
		};

		final String DAY[] = new String[]{
				"初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
				"十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
				"廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"
		};

		return GAN[(mc.age - 14) % GAN.length] + ZHI[(mc.age - 14) % ZHI.length] + "年" +
				MONTH[(mc.month)] + "月" +
				DAY[(mc.day)];
	}

	public static Npc getNpc(int index) {
		if (npc == null) {
			npc = LoadingScreen.loadNpcJson();
		}
		return npc.get(index);
	}


	/**
	 * @return npc
	 */
	public static ArrayList<Npc> getNpc() {
		if (npc == null) {
			npc = LoadingScreen.loadNpcJson();
		}
		return npc;
	}

	static class tdp {
		static ArrayList<tdp> talentDesc;

		public int id;
		public TalentDesc mTalentDesc;

		/**
		 * @return sa
		 */
		static SparseArray<TalentDesc> getSa() {
			SparseArray<TalentDesc> sa = new SparseArray<>();

			for (tdp i : talentDesc) {
				sa.put(i.id, i.mTalentDesc);
			}

			return sa;
		}

	}

	/**
	 * @return talent_desc
	 */
	public static SparseArray<TalentDesc> getTalent_desc() {
		if (talent_desc == null) {
			talent_desc = new SparseArray<>();

			BLGFileIO f = (BLGFileIO) Game.getInstance().getFileIO();
			BufferedReader in = null;

			try {
				in = new BufferedReader(new InputStreamReader(f.readAsset("data/TalentDesc.dat")));
				String s = "";

				s = in.readLine();
				Gson gson = new Gson();
				tdp.talentDesc = gson.fromJson(s, new TypeToken<ArrayList<tdp>>() {
				}.getType());
				talent_desc = tdp.getSa();

			} catch (IOException | JsonSyntaxException e) {
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}

		}

		return talent_desc;
	}

	public static int getGameDay() {
		return (mc.age - 14) * 360 + mc.month * 30 + mc.day;
	}

}
